package com.boxman;

import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Handler.Callback;
import android.os.Looper;
import android.os.Message;
import android.view.View;

import androidx.annotation.NonNull;

import java.io.InputStream;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;

// 小人
class Man extends Box implements Callback {
    // 定时器任务类
    private static class GameTimerTask extends TimerTask {
        private final Handler mCallback;    // 回调

        /**
         * 构造方法。
         * @param callback  回调
         */
        public GameTimerTask(Callback callback) {
            mCallback = new Handler(Looper.getMainLooper(), callback);
        }

        /**
         * 定时器事件的响应方法。
         */
        @Override
        public void run() {
            mCallback.sendEmptyMessage(Const.UM_TIMER);
        }
    }

    private Bitmap mCurrentImage1;      // 当前图片1
    private Bitmap mCurrentImage2;      // 当前图片2
    private final View mGameBoard;      // 游戏区域
    private Bitmap mImageLeft1;         // 左图片1
    private Bitmap mImageLeft2;         // 左图片2
    private Bitmap mImageRight1;        // 右图片1
    private Bitmap mImageRight2;        // 右图片2
    private Bitmap mImageUp1;           // 上图片1
    private Bitmap mImageUp2;           // 上图片2
    private final TimerTask mTimerTask; // 定时器任务

    /**
     * 构造方法。
     * @param assetManager  资产管理者
     * @param back          背后对象
     * @param drawer        绘图者
     * @param gameBoard     游戏区域
     * @param type          类型
     * @param x, y          左上角坐标
     */
    public Man(AssetManager assetManager, BaseGameObject back, Canvas drawer, View gameBoard, Type type, int x, int y) {
        super(assetManager, back, drawer, type, x, y);

        // 初始化成员
        mCurrentImage1 = mImage;
        mCurrentImage2 = mImage2;
        mGameBoard = gameBoard;

        // 加载所有图片
        String imageFilePath;
        InputStream inputStream;
        try {
            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 2);
            inputStream = assetManager.open(imageFilePath);
            mImageLeft1 = BitmapFactory.decodeStream(inputStream);

            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 3);
            inputStream = assetManager.open(imageFilePath);
            mImageLeft2 = BitmapFactory.decodeStream(inputStream);

            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 4);
            inputStream = assetManager.open(imageFilePath);
            mImageRight1 = BitmapFactory.decodeStream(inputStream);

            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 5);
            inputStream = assetManager.open(imageFilePath);
            mImageRight2 = BitmapFactory.decodeStream(inputStream);

            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 6);
            inputStream = assetManager.open(imageFilePath);
            mImageUp1 = BitmapFactory.decodeStream(inputStream);

            imageFilePath = String.format(Locale.getDefault(), Const.IMAGE_FILE_PATH, type.ordinal() * 10 + 7);
            inputStream = assetManager.open(imageFilePath);
            mImageUp2 = BitmapFactory.decodeStream(inputStream);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 开始跳舞
        mTimerTask = new GameTimerTask(this);
        new Timer().schedule(mTimerTask, Const.TIMER_INIT, Const.TIMER_INIT);
    }

    /**
     * 自定义事件的响应方法。
     * @param message   事件相关信息
     */
    @Override
    public boolean handleMessage(@NonNull Message message) {
        if (mCurrentImage == mCurrentImage1) {
            mCurrentImage = mCurrentImage2;
        } else {
            mCurrentImage = mCurrentImage1;
        }
        final Rect srcRect = new Rect(0, 0, mCurrentImage.getWidth(), mCurrentImage.getHeight());
        final Rect dstRect = new Rect(mX * sSize, mY * sSize, (mX + 1) * sSize, (mY + 1) * sSize);
        mDrawer.drawBitmap(mCurrentImage, srcRect, dstRect, null);
        mGameBoard.invalidate(dstRect);

        return true;
    }

    /**
     * 移动。
     * @param direction     方向
     * @param moveResult    移动结果
     * @return 被推动的箱子
     */
    @Override
    public BaseGameObject move(int direction, MoveResult moveResult) {
        int destX = mX, destY = mY; // 新位置的坐标

        // 根据方向，计算新位置的坐标和图片
        if (direction == R.id.IDC_BUTTON_LEFT) {
            destX--;
            mCurrentImage1 = mImageLeft1;
            mCurrentImage2 = mImageLeft2;
        } else if (direction == R.id.IDC_BUTTON_RIGHT) {
            destX++;
            mCurrentImage1 = mImageRight1;
            mCurrentImage2 = mImageRight2;
        } else if (direction == R.id.IDC_BUTTON_UP) {
            destY--;
            mCurrentImage1 = mImageUp1;
            mCurrentImage2 = mImageUp2;
        } else if (direction == R.id.IDC_BUTTON_DOWN) {
            destY++;
            mCurrentImage1 = mImage;
            mCurrentImage2 = mImage2;
        }

        // 重新设置图片
        mCurrentImage = mCurrentImage1;

        // 先移动旁边的物体
        final BaseGameObject box = Game.sBaseGameObjects[destY][destX].move(direction, moveResult);
        if (moveResult.result == MoveResult.Result.NO_MOVE) {
            return null;
        }

        // 移动小人
        super.move(direction, moveResult);

        return box;
    }

    /**
     * 停止跳舞。
     */
    public void stopDancing() {
        mTimerTask.cancel();
    }
}
